package cn.lena.hadoop.HDFS;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
import org.junit.Test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

/**
 * IO流操作HDFS文件的上传、下载
 * @author lena
 * @date 2021/5/17
 */
public class IO {

	/**
	 * 文件上传
	 */
	@Test
	public void uploadFile() throws IOException,InterruptedException,URISyntaxException{

		// 获取fs对象
		Configuration conf=new Configuration();
		//TODO:第一个的参数应为真实的服务器信息，第三个参数应为真实服务器用户
		FileSystem fs= FileSystem.get(new URI("hdfs://hadoop102:9000"),conf,"atguigu");

		// 获取输入流 TODO:输入想要上传文件的路径
		FileInputStream fis=new FileInputStream(new File("e:/test.txt"));

		// 获取输出流 TODO:要将文件上传到hdfs的路径
		FSDataOutputStream fos = fs.create(new Path("/test.txt"));

		// 输入输出流直接的拷贝 TODO:将fis流的内容拷贝到fos流
		IOUtils.copyBytes(fis,fos,conf);

		// 释放资源
		IOUtils.closeStream(fis);
		IOUtils.closeStream(fos);
		fs.close();

	}

	/**
	 * 文件下载
	 */
	@Test
	public void downloadFile() throws IOException,InterruptedException,URISyntaxException{

		// 获取fs对象
		Configuration conf=new Configuration();
		//TODO:第一个的参数应为真实的服务器信息，第三个参数应为真实服务器用户
		FileSystem fs= FileSystem.get(new URI("hdfs://hadoop102:9000"),conf,"atguigu");

		// 获取输入流 TODO:要下载文件在hdfs的路径
		FSDataInputStream fis = fs.open(new Path("/test.txt"));

		// 获取输出流 TODO:要将文件下载到本地哪个位置
		FileOutputStream fos=new FileOutputStream(new File("e:/test.txt"));

		// 输入输出流直接的拷贝 TODO:将fis流的内容拷贝到fos流
		IOUtils.copyBytes(fis,fos,conf);

		// 释放资源
		IOUtils.closeStream(fis);
		IOUtils.closeStream(fos);
		fs.close();

	}

	/**
	 * 下载文件的第一块
	 */
	@Test
	public void downloadFileFirst() throws IOException,InterruptedException,URISyntaxException{

		// 获取fs对象
		Configuration conf=new Configuration();
		//TODO:第一个的参数应为真实的服务器信息，第三个参数应为真实服务器用户
		FileSystem fs= FileSystem.get(new URI("hdfs://hadoop102:9000"),conf,"atguigu");

		// 获取输入流 TODO:要下载文件在hdfs的路径
		FSDataInputStream fis = fs.open(new Path("/bigFile.tar.gz"));

		// 获取输出流 TODO:要将文件下载到本地哪个位置
		FileOutputStream fos=new FileOutputStream(new File("e:/bigFile.tar.gz.first"));

		// 输入输出流直接的拷贝 TODO:将fis流的内容拷贝到fos流
		byte[] b=new byte[1024];
		for(int i=0;i<1024*128;i++){
			fis.read(b);	//读
			fos.write(b);	//写
		}

		// 释放资源
		IOUtils.closeStream(fis);
		IOUtils.closeStream(fos);
		fs.close();

	}

	/**
	 * 从文件特定位置开始下载
	 */
	@Test
	public void downloadFileAppoint() throws IOException,InterruptedException,URISyntaxException{

		// 获取fs对象
		Configuration conf=new Configuration();
		//TODO:第一个的参数应为真实的服务器信息，第三个参数应为真实服务器用户
		FileSystem fs= FileSystem.get(new URI("hdfs://hadoop102:9000"),conf,"atguigu");

		// 获取输入流 TODO:要下载文件在hdfs的路径
		FSDataInputStream fis = fs.open(new Path("/bigFile.tar.gz"));
		//TODO:指定文件读取的起点
		fis.seek(1024*1024*128);	//从128M读取，当前HDFS默认一块是128M，因此是读取文件第二块

		// 获取输出流 TODO:要将文件下载到本地哪个位置
		FileOutputStream fos=new FileOutputStream(new File("e:/bigFile.tar.gz.second"));

		// 输入输出流直接的拷贝 TODO:将fis流的内容拷贝到fos流
		IOUtils.copyBytes(fis,fos,conf);

		// 释放资源
		IOUtils.closeStream(fis);
		IOUtils.closeStream(fos);
		fs.close();

	}

}
